package com.runfast.waimai.utils;

import com.qiniu.common.QiniuException;
import com.qiniu.common.Zone;
import com.qiniu.http.Response;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.DefaultPutRet;
import com.qiniu.util.Auth;
import org.springframework.util.Assert;

import javax.imageio.ImageIO;
import javax.imageio.stream.ImageOutputStream;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

import static javax.imageio.ImageIO.read;

/**
 * @author: Mr.Jiao
 * @date: 2018年08月15日
 */
public class UploadImageUtil {

    private UploadImageUtil(){}

    //支持上传的图片类型
    private String[] suffixs = {".jpg",".png",".jpeg",".gif",".bmp"};

    private Auth auth;

    private UploadManager uploadManager;

    private String BUCKET_NAME;

    private int width = 200;

    private int height = 200;

    public UploadImageUtil(String ACCESS_KEY, String SECRET_KEY, String BUCKET_NAME) {
        this.BUCKET_NAME = BUCKET_NAME;
        //密钥配置
        auth = Auth.create(ACCESS_KEY, SECRET_KEY);

        Configuration cfg = new Configuration(Zone.zone2());
        //创建上传对象
        uploadManager = new UploadManager(cfg);
    }

    public UploadResult exec(String filename,InputStream is){
        return this.exec(filename, null, is, false);
    }

    public void setWidth(int width) {
        this.width = width;
    }

    public void setHeight(int height) {
        this.height = height;
    }

    public UploadResult execWithThumbnail(String filename, InputStream is){
        String suffix = this.getExtension(filename);
        //缩略图名称
        String thumbnailName = String.format("%s_thumbnail%s", filename.substring(0,filename.length() -suffix.length()),suffix);
        return this.exec(filename, thumbnailName, is, true);
    }

    public UploadResult execWithThumbnail(String filename, InputStream is, int width, int height){
        String suffix = this.getExtension(filename);
        //缩略图名称
        String thumbnailName = String.format("%s_thumbnail%s", filename.substring(0,filename.length() -suffix.length()),suffix);
        this.width = width;
        this.height = height;
        return this.exec(filename, thumbnailName, is, true);
    }

    public UploadResult exec(String filename, String thumbnailName, InputStream is,boolean useThumbnail) {
        if(!this.supported(filename)){
            return UploadResult.fail("不支持的文件类型");
        }
        String originalUrl = null;
        try {
            originalUrl = this.execute(filename, is);
        } catch (QiniuException e) {
            return UploadResult.fail(e.error());
        }
        String thumbnailUrl = null;
        if(useThumbnail){
            ByteArrayOutputStream byteArrayOutputStream = null;
            ImageOutputStream imageOutput = null;
            InputStream inputStream = null;
            try {
                //压缩图像
                BufferedImage bi = this.resize(ImageIO.read(is), width, height, true);
                byteArrayOutputStream = new ByteArrayOutputStream();
                imageOutput = ImageIO.createImageOutputStream(byteArrayOutputStream);
                ImageIO.write(bi, "png", imageOutput);
                inputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
                thumbnailUrl = this.execute(thumbnailName, inputStream);
            } catch (IOException e) {
                return UploadResult.fail("生成缩略图出错！");
            }finally {
                if(inputStream != null) {
                    try {
                        inputStream.close();
                    } catch (IOException e) {
                    }
                }
                if(imageOutput != null) {
                    try {
                        imageOutput.close();
                    } catch (IOException e) {
                    }
                }
                if(byteArrayOutputStream != null) {
                    try {
                        byteArrayOutputStream.close();
                    } catch (IOException e) {
                    }
                }
            }
        }
        return UploadResult.ok(useThumbnail, originalUrl, thumbnailUrl);
    }

    public boolean supported(String originalFilename){
        String suffix = this.getExtension(originalFilename);
        for(String v : suffixs){
            if(suffix.equalsIgnoreCase(v)){
                return true;
            }
        }
        return false;
    }

    public String execute(String filename,InputStream is) throws QiniuException {
        Response res = null;
        try{
            res = uploadManager.put(is, filename, auth.uploadToken(BUCKET_NAME), null, null);
            if(res.isOK()){
                DefaultPutRet putRet = res.jsonToObject(DefaultPutRet.class);
                return putRet.key;
            }
        }finally {
            if(res != null) {
                res.close();
            }
        }
        return null;
    }

    /**
     * @param im
     *            原始图像
     * @return 返回处理后的图像
     */
    public BufferedImage resize(BufferedImage im, int width,int height,boolean proportion) {
        int newWidth;
        int newHeight;
        // 判断是否是等比缩放
        if (proportion) {
            // 为等比缩放计算输出的图片宽度及高度
            double rate1 = ((double) im.getWidth(null)) / (double) width + 0.1;
            double rate2 = ((double) im.getHeight(null)) / (double) height + 0.1;
            // 根据缩放比率大的进行缩放控制
            double rate = rate1 < rate2 ? rate1 : rate2;
            newWidth = (int) (((double) im.getWidth(null)) / rate);
            newHeight = (int) (((double) im.getHeight(null)) / rate);
        } else {
            newWidth = width; // 输出的图片宽度
            newHeight = height; // 输出的图片高度
        }
        /* 新生成结果图片 */
        BufferedImage result = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB);
        result.getGraphics().drawImage(im.getScaledInstance(newWidth, newHeight, java.awt.Image.SCALE_AREA_AVERAGING), 0, 0,
                null);
        return result;
    }

    /**
     * 返回文件的文件后缀名
     *
     * @param fileName
     * @return
     */
    public String getExtension(String fileName) {
        try {
            return fileName.split("\\.")[fileName.split("\\.").length - 1];
        } catch (Exception e) {
            return null;
        }
    }

    public static class UploadResult {

        /**
         * 是否有缩略图
         */
        private boolean hasThumbnail;
        /**
         * 是否出现错误
         */
        private boolean hasError;
        /**
         * 消息
         */
        private String msg;

        /**
         * 缩略图
         */
        private String thumbnailUrl;

        /**
         * 原图地址
         */
        private String originalUrl;

        public boolean isHasThumbnail() {
            return hasThumbnail;
        }

        public boolean isHasError() {
            return hasError;
        }

        public String getMsg() {
            return msg;
        }

        public String getThumbnailUrl() {
            return thumbnailUrl;
        }

        public String getOriginalUrl() {
            return originalUrl;
        }

        public static UploadResult fail(String msg){
            UploadResult result = new UploadResult();
            result.hasError = true;
            result.msg = msg;
            return result;
        }

        public static UploadResult ok(boolean hasThumbnail,String originalUrl, String thumbnailUrl){
            UploadResult result = new UploadResult();
            result.hasError = false;
            result.hasThumbnail = hasThumbnail;
            result.originalUrl = originalUrl;
            result.thumbnailUrl = thumbnailUrl;
            return result;
        }
    }

}
